//package com.iwdnb.gkgz.common.utils;
//
//import java.math.BigDecimal;
//import java.util.ArrayList;
//import java.util.Collections;
//import java.util.LinkedHashMap;
//import java.util.List;
//import java.util.Map;
//import java.util.Objects;
//import java.util.stream.Collectors;
//
//import cn.hutool.core.date.DateUtil;
//import com.google.common.collect.Lists;
//import com.iwdnb.bmnf.common.utils.BeanConvertUtils;
//import com.iwdnb.bmnf.common.utils.BooleanUtils;
//import com.iwdnb.gkgz.common.model.dto.StockDayData;
//import com.iwdnb.gkgz.common.model.dto.StockSupportDTO;
//import com.iwdnb.gkgz.common.model.dto.StockSupportDTO.StockSupportCheckInfo;
//import com.iwdnb.gkgz.common.model.dto.StockSupportDTO.StockSupportItem;
//import com.iwdnb.gkgz.common.quota.MovingAverage;
//import lombok.extern.slf4j.Slf4j;
//import org.apache.commons.collections4.CollectionUtils;
//import org.apache.commons.lang3.StringUtils;
//import org.springframework.stereotype.Component;
//
//import static com.iwdnb.gkgz.common.utils.BigDecimalUtils.onePointZeroOneOne;
//import static com.iwdnb.gkgz.common.utils.StockUtils.getAveragePrice;
//
//@Slf4j
//@Component
//public class TulongdaoUtilsNew {
//    private static final int fivePeriod = 5;
//    public static final int sevenPeriod = 7;
//    private static final int tenPeriod = 10;
//    private static final int thirteenPeriod = 13;
//    private static final int twentyPeriod = 20;
//    private static final int thirtyPeriod = 30;
//    private static final int sixtyPeriod = 60;
//    public static final List<Integer> ALL_PERIODS = Lists.newArrayList(twentyPeriod, thirteenPeriod, tenPeriod,
//        thirtyPeriod);
//    private static final Map<Integer, String> PERIOD_MAP = new LinkedHashMap<>();
//
//    public static final BigDecimal ten = new BigDecimal(10);
//    public static final BigDecimal ninePointSix = new BigDecimal(9.6);
//    public static final BigDecimal seven = new BigDecimal(7);
//    public static final BigDecimal sixPointFive = new BigDecimal(6.5);
//    public static final BigDecimal five = new BigDecimal(5);
//    public static final BigDecimal three = new BigDecimal(3);
//
//    public static final BigDecimal twoPointOne = new BigDecimal(2.1);
//    public static final BigDecimal two = new BigDecimal(2);
//    public static final BigDecimal onePointOne = new BigDecimal(1.1);
//    public static final BigDecimal one = new BigDecimal(1);
//    public static final BigDecimal zero = new BigDecimal(0);
//    public static final BigDecimal zeroPointFive = new BigDecimal(0.5);
//
//    /**
//     * 预测明日股票屠龙刀支撑价格
//     *
//     * @param code
//     * @param stockDayDataList
//     * @param closePrice
//     * @return
//     */
//    public static StockSupportDTO predictTldSupportPrice(String code, List<StockDayData> stockDayDataList,
//        BigDecimal limitUpClosePrice) {
//        limitUpClosePrice = BigDecimalUtils.multiply(limitUpClosePrice, BigDecimalUtils.zeroPointNineSixFive);
//        StockSupportDTO stockSupportDTO = new StockSupportDTO();
//        stockSupportDTO.setCode(code);
//        StockDayData latestData = BeanConvertUtils.convert(stockDayDataList.get(stockDayDataList.size() - 1),
//            StockDayData.class);
//        BigDecimal closePrice = latestData.getClosePrice();
//        BigDecimal limitUpPrice = BigDecimalUtils.multiply(closePrice, BigDecimalUtils.onePointOne);
//        BigDecimal limitDownPrice = BigDecimalUtils.multiply(closePrice, BigDecimalUtils.zeroPointNine);
//        latestData.setOpenPrice(limitUpClosePrice);
//        latestData.setClosePrice(limitUpClosePrice);
//        latestData.setMaxPrice(limitUpClosePrice);
//        latestData.setMinPrice(limitUpClosePrice);
//        stockDayDataList = BeanConvertUtils.convertList(stockDayDataList, StockDayData.class);
//        stockDayDataList.add(latestData);
//        MovingAverage.calculateEMA(stockDayDataList, ALL_PERIODS);
//        List<StockSupportItem> supportItems = new ArrayList<>();
//        for (Integer period : ALL_PERIODS) {
//            BigDecimal avg = getFixedAveragePrice(latestData, period);
//            //均线在涨停板之上，跳过
//            if (BigDecimalUtils.isGt(avg, limitUpPrice)) {
//                log.error("{}-{} avg isGreatThan limitUpPrice,ignore,avg:{},limitUpPrice:{}", code, period, avg,
//                    limitUpPrice);
//                continue;
//            }
//            //买入价在涨停价下3.5%以上，换算一下均线在买入价4.57以上，跳过
//            if (BigDecimalUtils.isGt(avg, limitUpClosePrice)) {
//                log.error("{}-{} avg isGreatThan limitUpClosePrice,ignore,avg:{},limitUpClosePrice:{}", code, period,
//                    avg,
//                    limitUpClosePrice);
//                continue;
//            }
//            //计算修正后的均线
//            BigDecimal fixPrice = calculateAvgStockPrice(limitUpClosePrice, avg, period);
//            BigDecimal fixAvg = getFixedAveragePrice(avg, limitUpClosePrice, fixPrice, period);
//            if (BigDecimalUtils.isGe(fixPrice, limitDownPrice)) {
//                log.info("{}-{} avg isMatch price:{},avg:{},fixAvg:{}", code, period, fixPrice, avg, fixAvg
//                );
//                StockSupportItem supportItem = new StockSupportItem();
//                supportItem.setPeriod(period);
//                supportItem.setPrice(fixAvg);
//                supportItem.setBuyPrice(BigDecimalUtils.multiply(fixAvg, BigDecimalUtils.onePointZeroOneTwo));
//                supportItems.add(supportItem);
//            }
//        }
//        if (CollectionUtils.isEmpty(supportItems)) {
//            return null;
//        }
//        Collections.sort(supportItems, (o1, o2) -> o2.getPrice().compareTo(o1.getPrice()));
//        //只有一条均线符合要求,就直接返回
//        if (supportItems.size() == 1) {
//            stockSupportDTO.setFirst(supportItems.get(0));
//            return stockSupportDTO;
//        }
//
//        BigDecimal firstPrice = supportItems.get(0).getPrice();
//        stockSupportDTO.setFirst(supportItems.get(0));
//        List<StockSupportItem> firstItems = getMatchSupportItem(supportItems, firstPrice);
//        if (CollectionUtils.isNotEmpty(firstItems)) {
//            List<Integer> periods = firstItems.stream().map(StockSupportItem::getPeriod).collect(Collectors.toList());
//            stockSupportDTO.getFirst().setJoinPeriod(StringUtils.join(periods, ","));
//        }
//        supportItems = supportItems.subList(firstItems.size(), supportItems.size());
//        //第二支撑位
//        if (CollectionUtils.isNotEmpty(supportItems)) {
//            BigDecimal secondPrice = supportItems.get(0).getPrice();
//            stockSupportDTO.setSecond(supportItems.get(0));
//            List<StockSupportItem> secondItems = getMatchSupportItem(supportItems, secondPrice);
//            if (CollectionUtils.isNotEmpty(secondItems)) {
//                List<Integer> periods = secondItems.stream().map(StockSupportItem::getPeriod).collect(
//                    Collectors.toList());
//                stockSupportDTO.getSecond().setJoinPeriod(StringUtils.join(periods, ","));
//            }
//            supportItems = supportItems.subList(secondItems.size(), supportItems.size());
//        }
//        //第三支撑位
//        if (CollectionUtils.isNotEmpty(supportItems)) {
//            BigDecimal thirdPrice = supportItems.get(0).getPrice();
//            stockSupportDTO.setThird(supportItems.get(0));
//            List<StockSupportItem> thirdItems = getMatchSupportItem(supportItems, thirdPrice);
//            if (CollectionUtils.isNotEmpty(thirdItems)) {
//                List<Integer> periods = thirdItems.stream().map(StockSupportItem::getPeriod).collect(
//                    Collectors.toList());
//                stockSupportDTO.getThird().setJoinPeriod(StringUtils.join(periods, ","));
//            }
//        }
//        return stockSupportDTO;
//    }
//
//    public static void checkPreditctionOld(StockSupportDTO stockSupport, StockDayData data, StockDayData afterData) {
//        String remark = null;
//        String matchFlag = null;
//        BigDecimal compareRate = BigDecimalUtils.three;
//        BigDecimal closePrice = data.getClosePrice();
//        BigDecimal price = BigDecimalUtils.isGe(closePrice, afterData.getOpenPrice())
//            ? afterData.getOpenPrice() : closePrice;
//        if (Objects.nonNull(afterData)) {
//            stockSupport.setRealtimePrice(afterData.getClosePrice());
//            stockSupport.setOpenPrice(afterData.getOpenPrice());
//            stockSupport.setMinPrice(afterData.getMinPrice());
//        }
//        BigDecimal supportPrice = null;
//        Integer supportLevel = null;
//        BigDecimal firstSupportPrice = stockSupport.getFirst().getPrice();
//        //第一支撑位比昨日收盘价低3个点以上，第一支撑位有效
//        BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(price, firstSupportPrice);
//        if (BigDecimalUtils.isGe(rate, compareRate)) {
//            BigDecimal supportRate = BigDecimalUtils.subStractAndDividePrecent(closePrice, firstSupportPrice);
//            BigDecimal minRate = BigDecimalUtils.subStractAndDividePrecent(firstSupportPrice,
//                afterData.getMinPrice());
//            if (BigDecimalUtils.isGe(supportRate, BigDecimalUtils.eight)) {
//                matchFlag = BooleanUtils.FALSE;
//                remark = "第一支撑跌幅过大,与开盘价相差" + supportRate + "%";
//            } else if (BigDecimalUtils.isGe(minRate, BigDecimalUtils.fuOnePointOne)) {
//                matchFlag = BooleanUtils.TRUE;
//                supportLevel = 1;
//                supportPrice = firstSupportPrice;
//                remark = "第一支撑有效,与最低价相差" + minRate + "%";
//            } else {
//                matchFlag = BooleanUtils.FALSE;
//                remark = "第一支撑有效,但未到支撑,与最低价相差" + minRate + "%";
//            }
//        } else if (Objects.nonNull(stockSupport.getSecond())) {
//            //验证第二支撑
//            BigDecimal secondSupportPrice = stockSupport.getSecond().getPrice();
//            BigDecimal supportRate = BigDecimalUtils.subStractAndDividePrecent(closePrice, secondSupportPrice);
//            rate = BigDecimalUtils.subStractAndDividePrecent(price, secondSupportPrice);
//            //第二支撑跌幅过大跌幅过大
//            if (BigDecimalUtils.isGe(supportRate, BigDecimalUtils.eight)) {
//                matchFlag = BooleanUtils.FALSE;
//                remark = "第二支撑跌幅过大,与开盘价相差" + supportRate + "%";
//            } else if (BigDecimalUtils.isLt(afterData.getOpenPrice(), secondSupportPrice)) {
//                //开盘价跌破第二支撑
//                remark = "开盘价跌破第二支撑";
//                matchFlag = BooleanUtils.FALSE;
//            } else if (BigDecimalUtils.isGe(rate, compareRate)) {
//                //与基准价格差额到达3个点以上，第二支撑有效
//                BigDecimal minRate = BigDecimalUtils.subStractAndDividePrecent(secondSupportPrice,
//                    afterData.getMinPrice());
//                //股价到达第二支撑
//                if (BigDecimalUtils.isGe(minRate, BigDecimalUtils.fuOnePointOne)) {
//                    matchFlag = BooleanUtils.TRUE;
//                    supportLevel = 2;
//                    supportPrice = secondSupportPrice;
//                    remark = "第二支撑有效,与最低价相差" + minRate + "%";
//                } else {
//                    //股价未到达第二支撑
//                    matchFlag = BooleanUtils.FALSE;
//                    remark = "第二支撑有效,但未到支撑,与最低价相差" + minRate + "%";
//                }
//
//            } else {
//                remark = "第二支撑无效";
//                matchFlag = BooleanUtils.FALSE;
//            }
//        } else {
//            remark = "无第二支撑";
//            matchFlag = BooleanUtils.FALSE;
//        }
//        stockSupport.setRemark(remark);
//        stockSupport.setMatchFlag(matchFlag);
//        stockSupport.setSupportLevel(supportLevel);
//        if (Objects.nonNull(supportPrice)) {
//            supportPrice = BigDecimalUtils.multiply(supportPrice, onePointZeroOneOne);
//            stockSupport.setSupportPrice(supportPrice);
//            stockSupport.setRealtimeRate(
//                BigDecimalUtils.subStractAndDividePrecent(afterData.getClosePrice(), supportPrice));
//        }
//    }
//
//    public static void checkPreditction(StockSupportDTO stockSupport, StockDayData data, StockDayData afterData) {
//        if (Objects.isNull(afterData)) {
//            return;
//        }
//        stockSupport.setDate(afterData.getDate());
//        stockSupport.setRealtimePrice(afterData.getClosePrice());
//        stockSupport.setOpenPrice(afterData.getOpenPrice());
//        stockSupport.setMinPrice(afterData.getMinPrice());
//        int markEmotion = 9;
//        int currentEmotion = 9;
//        StockSupportCheckInfo checkInfo = checkSupport(stockSupport.getFirst(), 1, data, afterData, markEmotion,
//            currentEmotion);
//        if (BooleanUtils.isTrue(checkInfo.getMatchFlag())) {
//            setMatchCheckInfo(stockSupport, checkInfo, afterData, markEmotion, currentEmotion);
//            return;
//        }
//        if (Objects.nonNull(stockSupport.getSecond())) {
//            checkInfo = checkSupport(stockSupport.getSecond(), 2, data, afterData, markEmotion, currentEmotion);
//            if (BooleanUtils.isTrue(checkInfo.getMatchFlag())) {
//                setMatchCheckInfo(stockSupport, checkInfo, afterData, markEmotion, currentEmotion);
//                return;
//            }
//        }
//        if (Objects.nonNull(stockSupport.getThird())) {
//            checkInfo = checkSupport(stockSupport.getThird(), 3, data, afterData, markEmotion, currentEmotion);
//            if (BooleanUtils.isTrue(checkInfo.getMatchFlag())) {
//                setMatchCheckInfo(stockSupport, checkInfo, afterData, markEmotion, currentEmotion);
//                return;
//            }
//        }
//        //设置未匹配支撑位的信息
//        stockSupport.setRemark(checkInfo.getRemark());
//        stockSupport.setMatchFlag(checkInfo.getMatchFlag());
//
//    }
//
//    /**
//     * 是否涨停次日带上影线且上涨
//     *
//     * @param stockDayDataList
//     * @return
//     */
//    public static boolean isSignalAfterOneDateUpLineUp(List<StockDayData> stockDayDataList, String limitUpDate) {
//        String afterOneDate = DateUtil.formatDate(WorkDayUtils.getNextWorkDay(DateUtil.parseDate(limitUpDate)));
//        StockDayData limitUpdata = StockUtils.getStockDayData(stockDayDataList, limitUpDate);
//        StockDayData afterOneData = StockUtils.getStockDayData(stockDayDataList, afterOneDate);
//        if (Objects.isNull(limitUpdata) || Objects.isNull(afterOneData)) {
//            return false;
//        }
//        BigDecimal upPrice = BigDecimalUtils.isGe(afterOneData.getClosePrice(), afterOneData.getOpenPrice())
//            ? afterOneData.getClosePrice() : afterOneData.getOpenPrice();
//        BigDecimal upLineRate = BigDecimalUtils.subStractAndDividePrecent(afterOneData.getMaxPrice(), upPrice);
//        BigDecimal afterRate = BigDecimalUtils.subStractAndDividePrecent(afterOneData.getClosePrice(),
//            limitUpdata.getClosePrice());
//        if (BigDecimalUtils.isGe(upLineRate, BigDecimalUtils.one)
//            && BigDecimalUtils.isGe(afterRate, BigDecimalUtils.zeroPointFive)) {
//            return true;
//        }
//        return false;
//    }
//
//    private static void setMatchCheckInfo(StockSupportDTO stockSupport, StockSupportCheckInfo checkInfo,
//        StockDayData afterData, int markEmotion, int currentEmotion) {
//        stockSupport.setSupportLevel(checkInfo.getSupportLevel());
//        stockSupport.setRemark(checkInfo.getRemark());
//        stockSupport.setMatchFlag(checkInfo.getMatchFlag());
//        BigDecimal supportPrice = checkInfo.getSupportPrice();
//        supportPrice = BigDecimalUtils.multiply(supportPrice, BigDecimalUtils.onePointZeroOneOne);
//        stockSupport.setSupportPrice(supportPrice);
//        stockSupport.setRealtimeRate(
//            BigDecimalUtils.subStractAndDividePrecent(afterData.getClosePrice(), supportPrice));
//    }
//
//    private static StockSupportCheckInfo checkSupport(StockSupportItem supportItem,
//        int index, StockDayData data,
//        StockDayData afterData, int markEmotion, int currentEmotion) {
//        BigDecimal supportPrice = supportItem.getPrice();
//        BigDecimal closePrice = data.getClosePrice();
//        BigDecimal basicPrice = BigDecimalUtils.divide(closePrice.add(afterData.getOpenPrice()), BigDecimalUtils.two);
//        BigDecimal supportRate = BigDecimalUtils.subStractAndDividePrecent(closePrice, supportPrice);
//        BigDecimal minRate = BigDecimalUtils.subStractAndDividePrecent(supportPrice,
//            afterData.getMinPrice());
//        //支撑位比昨日收盘价低3个点以上，支撑位有效
//        BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(basicPrice, supportPrice);
//        StockSupportCheckInfo checkInfo = new StockSupportCheckInfo();
//        BigDecimal compareRate = getCompareRate(markEmotion, currentEmotion);
//        BigDecimal supportCompareRate = getSupportCompareRate(markEmotion, currentEmotion);
//        BigDecimal supportPriceRate = getSupportPriceRate(markEmotion, currentEmotion);
//        if (BigDecimalUtils.isGe(supportRate, BigDecimalUtils.eightPointEight)) {
//            checkInfo.setMatchFlag(BooleanUtils.FALSE);
//            checkInfo.setRemark("第" + index + "支撑跌幅过大,与开盘价相差" + supportRate + "%");
//        } else if (BigDecimalUtils.isLt(afterData.getOpenPrice(), supportPrice)) {
//            //开盘价跌破支撑
//            checkInfo.setMatchFlag(BooleanUtils.FALSE);
//            checkInfo.setRemark("开盘价跌破第" + index + "支撑");
//        } else if (BigDecimalUtils.isGe(rate, compareRate)) {
//            if (BigDecimalUtils.isGe(minRate, supportCompareRate)) {
//                checkInfo.setMatchFlag(BooleanUtils.TRUE);
//                checkInfo.setSupportLevel(index);
//                checkInfo.setSupportPrice(supportPrice);
//                checkInfo.setRemark("第" + index + "支撑有效,与最低价相差" + minRate + "%");
//            } else {
//                checkInfo.setMatchFlag(BooleanUtils.FALSE);
//                checkInfo.setRemark("第" + index + "支撑有效,但未到支撑,与最低价相差" + minRate + "%");
//            }
//        } else {
//            checkInfo.setMatchFlag(BooleanUtils.FALSE);
//            checkInfo.setRemark("第" + index + "支撑无效");
//        }
//        return checkInfo;
//    }
//
//    private static BigDecimal getCompareRate(int markEmotion, int currentEmotion) {
//        if (StockEmotionUtils.isActiveEmotion(markEmotion) && StockEmotionUtils.isActiveEmotion(currentEmotion)) {
//            Integer rate = 10 - currentEmotion;
//            return BigDecimalUtils.of(rate);
//        }
//        return BigDecimalUtils.three;
//    }
//
//    private static BigDecimal getSupportCompareRate(int markEmotion, int currentEmotion) {
//        if (StockEmotionUtils.isColdEmotion(markEmotion)) {
//            if (StockEmotionUtils.isNegativeEmotion(currentEmotion)) {
//                double rate = 1.9 - currentEmotion;
//                return BigDecimalUtils.of(rate);
//            }
//        }
//        if (StockEmotionUtils.isSensitiveEmotion(currentEmotion)) {
//            return BigDecimalUtils.zeroPointFive;
//        }
//        return BigDecimalUtils.fuOnePointOne;
//    }
//
//    private static BigDecimal getSupportPriceRate(int markEmotion, int currentEmotion) {
//        if (StockEmotionUtils.isColdEmotion(markEmotion)) {
//            if (StockEmotionUtils.isNegativeEmotion(currentEmotion)) {
//                double rate = 100 + currentEmotion - 1.9;
//                return BigDecimalUtils.of(rate / 100);
//            }
//        }
//        return BigDecimalUtils.onePointZeroOneOne;
//    }
//
//    private static List<StockSupportItem> getMatchSupportItem(List<StockSupportItem> supportItems, BigDecimal price) {
//        List<StockSupportItem> items = new ArrayList<>();
//        for (int i = 0; i < supportItems.size(); i++) {
//            StockSupportItem item = supportItems.get(i);
//            BigDecimal rate = BigDecimalUtils.subStractAndDividePrecent(price, item.getPrice());
//            if (BigDecimalUtils.isLe(rate, BigDecimalUtils.two)) {
//                items.add(item);
//                continue;
//            }
//            break;
//        }
//        return items;
//    }
//
//    private static BigDecimal calculateAvgStockPrice(BigDecimal limitUpPrice, BigDecimal avg, Integer period) {
//        //计算差价平均,与均线相减
//        BigDecimal priceRange = BigDecimalUtils.subtract(limitUpPrice, avg);
//        priceRange = BigDecimalUtils.divide(priceRange, new BigDecimal(period));
//        return BigDecimalUtils.subtract(avg, priceRange);
//    }
//
//    private static BigDecimal getFixedAveragePrice(StockDayData data, Integer period) {
//        BigDecimal avg = getAveragePrice(data, period);
//        //计算差价平均,与均线相减
//        BigDecimal priceRange = BigDecimalUtils.subtract(data.getClosePrice(), data.getMinPrice());
//        BigDecimal avgRange = BigDecimalUtils.divide(priceRange, new BigDecimal(period));
//        return BigDecimalUtils.subtract(avg, avgRange);
//    }
//
//    private static BigDecimal getFixedAveragePrice(BigDecimal avg, BigDecimal currentPrice, BigDecimal minPrice,
//        Integer period) {
//        //计算差价平均,与均线相减
//        BigDecimal priceRange = BigDecimalUtils.subtract(currentPrice, minPrice);
//        BigDecimal avgRange = BigDecimalUtils.divide(priceRange, new BigDecimal(period));
//        return BigDecimalUtils.subtract(avg, avgRange);
//    }
//
//}
